// 蜂窝蜜造平台生成代码，此文件只生成一次，不需要添加到 .beeignore

package com.fowo.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import cn.hutool.extra.template.engine.beetl.BeetlEngine;
import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.Product;
import com.fowo.api.entity.ProductSet;
import com.fowo.api.entity.ProductSetDetail;
import com.fowo.api.model.product.set.ProductSetSelectLifeProductParam;
import com.fowo.api.model.product.set.ProductSetSelectLifeProductResult;
import com.fowo.api.model.product.set.ProductSetVo;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.SysBase;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 产品生命周期设置 服务实现类
 */
@Slf4j
@Service
public class ProductSetServiceImpl extends ProductSetBaseServiceImpl {

    @Resource
    private ProductServiceImpl productService;
    @Resource
    private ProductSetDetailServiceImpl productSetDetailService;

    /**
     * 更新生命周期
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了更新生命周期操作"
    )
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void updateProductLifeTag(List<Long> ids) throws Exception {
        try {
            List<ProductSet> list = super.list(Wrappers.<ProductSet>lambdaQuery().eq(ProductSet::getStatus, "1").in(CollUtil.isNotEmpty(ids), ProductSet::getId, ids).orderByAsc(ProductSet::getLifeTag).orderByDesc(ProductSet::getId));
            if (CollUtil.isEmpty(list)) {
                return;
            }
            List<Product> productList = new ArrayList<>();
            List<ProductSetDetail> productSetDetailList = new ArrayList<>();
            for (ProductSet productSet : list) {
                if (StrUtil.equalsIgnoreCase("Amazon", productSet.getPlatform())) {
                    this.amazonLifeHandler(productSet, productList, productSetDetailList);
                }
            }
            productService.updateBatchById(productList,productList.size());
            productSetDetailService.saveBatch(productSetDetailList,productSetDetailList.size());
        } catch (Exception ex) {
            log.error("发生异常,异常信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
            throw new RuntimeException("发生异常,信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
        }
    }

    /**
     * 亚马逊生命周期处理
     *
     * @param productSet
     * @param productList
     * @param productSetDetailList
     */
    public void amazonLifeHandler(ProductSet productSet, List<Product> productList, List<ProductSetDetail> productSetDetailList) {
        ProductSetSelectLifeProductParam productParam = new ProductSetSelectLifeProductParam();
        productParam.setClassifys(productSet.getClassify());
        productParam.setHavingSql(this.prepareHavingSql(productSet.getExpress()));
        List<ProductSetSelectLifeProductResult> resultList = this.baseMapper.selectLifeProduct(productParam);
        if (CollUtil.isEmpty(resultList)) {
            return;
        }
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        //productService.update(Wrappers.<Product>lambdaUpdate().in(Product::getId, resultList.stream().map(m -> m.getId()).collect(Collectors.toList())).set(Product::getLifeTag, productSet.getLifeTag()));
        for (ProductSetSelectLifeProductResult item : resultList) {
            //更新产品
            Product product = new Product();
            product.setId(item.getId());
            product.setLifeTag(productSet.getLifeTag());
            CollUtil.addIfAbsent(productList, product);
            //新增记录
            ProductSetDetail productSetDetail = BeanUtil.copyProperties(item, ProductSetDetail.class);
            productSetDetail.setId(null);
            productSetDetail.setProductId(item.getId());
            productSetDetail.setCreateTime(new Date());
            //如果存在当前用户
            if (currentUser != null) {
                productSetDetail.setCreateUser(currentUser.getUserId());
            }
            productSetDetail.setDelFlag(false);
            CollUtil.addIfAbsent(productSetDetailList, productSetDetail);
        }
    }

    /**
     * 检查表达式
     *
     * @param express
     */
    private String prepareHavingSql(String express) {
        if (StrUtil.isBlank(express)) {
            return null;
        }


        Template template = TemplateUtil.createEngine().getTemplate(express);
        String result = template.render(Dict.create()
                .set("商品首单时间", "firstorderday")
                .set("总销量", "sumquantityordered")
                .set("销售金额", "ordertotalamount")
                .set("本地库存数量", "stockqty")
                .set("FBA库存数量", "fbastockqty")
                .set("月平均销量", "avgquantityordered"));
        return result;
    }

    /**
     * 拷贝
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了拷贝操作"
    )
    @Override
    public void copy(Long id) throws Exception {
        ProductSetVo byId = super.getVoById(id);
        ProductSetVo productSetVo = BeanUtil.copyProperties(byId, ProductSetVo.class, this.getIgnoreProperties());
        super.create(productSetVo);
    }


    /**
     * 拷贝忽略的字段
     *
     * @param ignoreProperties
     * @return
     */
    public String[] getIgnoreProperties(String... ignoreProperties) {
        String[] array = Arrays.stream(ReflectUtil.getFields(SysBase.class)).map(m -> ReflectUtil.getFieldName(m)).toArray(String[]::new);
        return ArrayUtil.append(ignoreProperties, array);
    }

}
